﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;

namespace 窗口背景透明
{
    public class ListData
    {
        public string FilePath { get; set; }
        public BitmapSource FileIcon { get; set; } // 图片内容
    }

    public partial class MainWindow : Window
    {
        private readonly string folderPath = @"D:\Downloads Files";
        private List<string> _allFiles = new List<string>();

        private readonly BitmapImage FilesIcon = new BitmapImage(new Uri(@"C:\Users\16602\Desktop\PNG素材\Folders.png"));

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this._allFiles = await GetAllFilesAsync(this.folderPath);
        }

        // 打印输出
        private void PrintfPath()
        {
            foreach (string file in this._allFiles)
            {
                Debug.WriteLine(file);
            }
        }

        // 遍历文件夹下的所有文件
        public static async Task<List<string>> GetAllFilesAsync(string folderPath)
        {
            List<string> files = new List<string>();

            // 检查文件夹是否存在
            if (!Directory.Exists(folderPath))
            {
                Debug.WriteLine("文件夹路径不存在: " + folderPath);
                return null;
            }
            // 使用队列存储需要遍历的文件夹路径
            Queue<string> folders = new Queue<string>();
            folders.Enqueue(folderPath);

            while (folders.Count > 0)
            {
                // 取出队列中的下一个文件夹
                string currentFolder = folders.Dequeue();

                try
                {

                    // 异步获取子文件夹并加入队列
                    foreach (string directory in Directory.GetDirectories(currentFolder))
                    {
                        files.Add(directory);
                        folders.Enqueue(directory);
                    }

                    // 异步获取当前文件夹中的文件
                    foreach (string file in Directory.GetFiles(currentFolder))
                    {
                        files.Add(file);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"无法访问文件夹 {currentFolder}: {ex.Message}");
                }

                // 等待一段时间，以便异步操作不会过度占用资源
                await Task.Yield();
            }

            return files;
        }

        // 异步模糊查询
        public async Task<List<string>> GetFilesContainingKeywordAsync(string keyword)
        {
            return await Task.Run(() => _allFiles.Where(file => file.Contains(keyword)).ToList());
        }

        // 根据字符串查询符合的内容
        public async Task<int> SetSearchData(List<string> Str)
        {
            await Dispatcher.InvokeAsync(() =>
            {
                List<string> _F = new List<string>();
                List<string> _D = new List<string>();
                BitmapImage _Bitmap = null;
                Str.ForEach(filePath =>
                {
                    var T = CheckPathType(filePath);
                    if (T.Item1 == 1)
                    {
                        _D.Add(filePath);
                    }
                    if (T.Item1 == 0)
                    {
                        _F.Add(filePath);
                    }
                });
                // 对 F 和 D 列表按名称进行排序
                _F.Sort();
                _D.Sort();
                // 合并两个已排序的列表
                List<string> combinedList = new List<string>();
                combinedList.AddRange(_D);  // 然后将 _D 列表添加到 combinedList
                combinedList.AddRange(_F);  // 先将 _F 列表添加到 combinedList

                combinedList.ForEach(file =>
                {
                    var T = CheckPathType(file);
                    if (T.Item1 == 1)
                    {
                        _Bitmap = FilesIcon;
                    }
                    else
                    {
                        _Bitmap = FileIconExtractor.GetFileIcon(file);
                    }
                    this.SearchData.Items.Add(new ListData
                    {
                        FileIcon = _Bitmap,
                        FilePath = T.Item2,
                    });

                });
                _F = null;
                _D = null;
                combinedList = null;

            });
            return Str.Count;
        }

        // 返回路径最后的层级
        public static string ReturnPahtLast(string path)
        {
            // 将路径分隔为各个部分
            string[] parts = path.Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar);
            // 直接返回原始路径最后一个层级
            return parts[parts.Length - 1];
        }

        // 检查文件路径类型
        private static (int, string) CheckPathType(string path)
        {
            if (Directory.Exists(path))
            {
                return (1, new DirectoryInfo(path).Name);
            }
            else if (File.Exists(path))
            {
                return (0, new FileInfo(path).Name);
            }
            else
            {
                return (-1, ReturnPahtLast(path));
            }
        }

        private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                try
                {
                    this.DragMove();
                }
                catch (InvalidOperationException ex)
                {
                    // 打印日志：处理异常，可能是由于不正确的鼠标事件触发
                    Debug.WriteLine("Error:" + ex.Message);
                }
            }
        }

        private void CloseCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        // 输入需要查询的内容
        private async void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            await Dispatcher.InvokeAsync(async () =>
            {
                if (new StringInfo(this.Seach.Text).LengthInTextElements > 0)
                {

                    this.SearchData.Items.Clear();
                    if (await SetSearchData(await GetFilesContainingKeywordAsync(this.Seach.Text)) > 0)
                    {
                        if (this.SearchResults.Visibility != Visibility.Visible)
                        {
                            this.SearchResults.Visibility = Visibility.Visible;
                        }
                    }
                    else
                    {
                        this.SearchResults.Visibility = Visibility.Collapsed;
                    }

                    Debug.WriteLine("Info:" + this.Seach.Text);
                }
                else
                {
                    this.SearchResults.Visibility = Visibility.Collapsed;
                    this.SearchData.Items.Clear();
                    Debug.WriteLine("Error:" + this.Seach.Text);
                }

            });
        }

    }
}
